///******************** NG.Respate(C)  **********************************
//* 产品名称: Respate 科技
//* 文件名称: signal.c
//* 程序作者: 雷帕特公司(南宫子萍)
//* 程序版本: V1.1														   
//* 编制日期: 2019/1/29
//* 功能描述: tftp服务器
//* QQ:	2085827949
//**********************************************************************/
#include "LapSocket.h"

// 创建套接字 并返回文件描述符
int Lap_Sockt(int family,int type,int port,char* ip,struct sockaddr_in* addr)
{
	int sockfd = socket(family,type,0);	// 创建套接字
	if(sockfd<0) return -1;

	addr->sin_family = family;			// IPV4
	addr->sin_port = htons(port);		// 端口
	if(NULL != ip)						// 指定IP
		addr->sin_addr.s_addr = inet_addr(ip);
	else 								// 任意IP
	 addr->sin_addr.s_addr = htonl(INADDR_ANY);

	return sockfd;	// 返回fd
}

// 创建udp的套接字 IPV4 UDP协议 并返回文件描述符
int Lap_UDP_Socket4(int port,char* ip,struct sockaddr_in* addr) 
{
	return Lap_Sockt(AF_INET,SOCK_DGRAM,port,ip,addr);
}

// 创建udp的套接字 IPV6 UDP协议 并返回文件描述符
int Lap_UDP_Socket6(int port,char* ip,struct sockaddr_in* addr) 
{
	// return Lap_Sockt(AF_INET,SOCK_DGRAM,port,ip,addr);
	return -1;
}



// 创建udp的套接字 IPV4 UDP协议 并返回文件描述符
int Lap_TCP_Socket4(int port,char* ip,struct sockaddr_in* addr) 
{
	return Lap_Sockt(AF_INET,SOCK_STREAM,port,ip,addr);
}


// 绑定端口(TCP/UDP)
int Lap_Bind(int sockfd,int reuse,struct sockaddr_in* addr)
{
	int on =1;
	int ret = 0;
	int level = -1;

	//设置端口复用
	if(reuse == IPPROTO_IP) level =IPPROTO_IP;
	else if(reuse == IPPROTO_IP) level =IPPROTO_TCP;
	else if (reuse > 0) level =SOL_SOCKET;
	if(level > 0) ret = setsockopt(sockfd,level,SO_REUSEADDR,&on,sizeof(on));
	if(ret < 0) return -1;

	//绑定地址信息，ip信息
	ret = bind(sockfd,(struct sockaddr*)addr,sizeof(struct sockaddr_in));
	if(ret < 0) return -2;
	return 0;
}


// 绑定端口(UDP to UDP)
int Lap_UDP_Connect(int port,char*ip,struct sockaddr_in *c_addr)
{
	struct sockaddr_in n_addr;
	int fd;

    fd = Lap_Sockt(PF_INET,SOCK_DGRAM,port,ip,(struct sockaddr_in *)&n_addr);
    if(fd < 0) return -1;   // 绑定失败
    Lap_fdNonBlock(fd);     //非阻塞
    
    int ret = Lap_Bind(fd,SOL_SOCKET,&n_addr);
	if(ret < 0) goto err1;

	ret = connect(fd,(struct sockaddr*)c_addr,sizeof(struct sockaddr_in));
    if(ret < 0) goto err1;
	return fd;  // 返回正确的fd

err1:
    close(fd);
    return -2;   // 绑定失败
}




#if 0
int main()
{
	LAP_ErrOutSet(NULL);

	struct sockaddr_in addr;
	struct sockaddr_in c_addr;

	int len = sizeof(struct sockaddr_in);

	int cfd = Lap_UDP_Socket4(8085,"192.168.20.243",&addr);
	if(cfd<0) return -1;

	int ret = Lap_Bind(cfd,-1,&addr);
	if(ret < 0) printf("Lap_Bind err:%d\r\n",ret);

	while (1)
	{
		char buff[1024]={0};
		int size = recvfrom(cfd,buff,sizeof(buff),0,(struct sockaddr *)&c_addr,&len);
		printf("recve len:%d str:%s\r\n",size,buff);
		sendto(cfd,buff,size,0,(struct sockaddr *)&c_addr,len);
	}

	return 0;
}
#endif

																						 
